﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using VisualAgile.Controllers;
using System.Web.Mvc;
using System.Web.Routing;
using VisualAgile.DTO;
using VisualAgile.DTO.Mappers;

namespace VisualAgile.Web.Tests
{
    /// <summary>
    /// Summary description for UserControllerTests
    /// </summary>
    [TestClass]
    public class UserControllerTests : BaseControllerTests
    {
        public static UserController GetController()
        {
            UserController controller = new UserController();
            ControllerContext controllerContext = new ControllerContext(new MockHttpContext(), new RouteData(), controller);
            controller.ControllerContext = controllerContext;
            return controller;
        }        

        [TestMethod]
        public void GetAction_Should_Return_View_For_User()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.GetUser(new Guid("2EBDBC36-3585-47b3-8709-BE3184956938"));

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");
            
            // Result should be true            
            Assert.IsTrue(actionData.Result, actionData.Message);

            //user data should not be null
            Assert.IsNotNull(actionData.Data, "User data is null");            
        }

        [TestMethod]
        public void GetAction_Should_Return_ViewNotFound_For_BogusUser()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.GetUser(Guid.Empty);

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsFalse(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("NotFound", actionData.Message);
        }

        [TestMethod]
        public void DeleteAction_Should_Return_Success()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.DeleteUser(new Guid("2EBDBC36-3585-47b3-8709-BE3184956938"));

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsTrue(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Success", actionData.Message);
        }

        [TestMethod]
        public void DeleteAction_Should_Return_Failure()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.DeleteUser(Guid.NewGuid());

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsFalse(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Failure", actionData.Message);
        }

        [TestMethod]
        public void DeleteAction_Should_Return_AccessDenied_For_Developer()
        {
            // Arrange
            var controller = GetController();

            controller.SetContextUserTo(FakeUserData.Developer());

            // Act
            var result = (JsonResult)controller.DeleteUser(Guid.NewGuid());

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsFalse(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("AccessDenied", actionData.Message);
        }


        [TestMethod]
        public void AddAction_Should_Add_And_Return_User()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.AddUser(new UserDTO()
            {
                CreateDate = DateTime.Now,
                Email = "test@test.com",                
                Mobile = "9886803882",
                Name = "test",
                Role = Role.Developer.Name                               
            });

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsTrue(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Success", actionData.Message);

            //user data should not be null
            Assert.IsNotNull(actionData.Data, "User data is null");   
        }

        [TestMethod]
        public void AddAction_Should_Not_Add_Existing_User()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.AddUser(new UserDTO()
            {
                CreateDate = DateTime.Now,
                Email = "test@test.com",
                Mobile = "9886803882",
                UserID = new Guid("2EBDBC36-3585-47b3-8709-BE3184956938"),
                Name = "test",
                Role = Role.Developer.Name
            });

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsFalse(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Failure", actionData.Message);            
        }

        [TestMethod]
        public void UpdateAction_Should_Update_And_Return_User()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.UpdateUser(new UserDTO()
            {
                CreateDate = DateTime.Now,
                Email = "test@test.com",
                Mobile = "9886803882",
                Name = "updated",
                UserID = new Guid("2EBDBC36-3585-47b3-8709-BE3184956938"),
                Role = Role.Developer.Name
            });

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsTrue(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Success", actionData.Message);

            //user data should not be null
            Assert.IsNotNull(actionData.Data, "User data is null");
        }

        [TestMethod]
        public void ChangePasswordAction_Should_Update_Password()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.ChangePassword("goodPass", "test");

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsTrue(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Success", actionData.Message);            
        }

        [TestMethod]
        public void ChangePasswordAction_Should_Not_Update_Password()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = (JsonResult)controller.ChangePassword("badPass", "newPass");

            // Results should be ResultDTO
            ResultDTO actionData = result.Data as ResultDTO;
            Assert.IsNotNull(actionData, "No results found");

            // Result should be true            
            Assert.IsFalse(actionData.Result, actionData.Message);

            // Assert
            Assert.AreEqual("Password didn't match, please try again.", actionData.Message);
        }

        [TestMethod]
        public void GetAllAction_Should_GetAll_Users()
        {
            // Arrange
            var controller = GetController();

            // Act
            var result = controller.GetAll();

            // Results should be ResultDTO            
            Assert.IsNotNull(result, "No results found");            
        }
    }
}
